package com.xjm.i1.core.context;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import com.xjm.i1.core.env.CommandLinePropertySource;
import com.xjm.i1.core.env.ExtraConfigPropertySource;
import com.xjm.i1.core.env.PropertySource;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 配置文件与启动参数加载器
 * */
@Slf4j
public class PropertySourceLoader {

    // 所有加载的配置文件
    private final Set<PropertySource<?>> propertySources = new LinkedHashSet<>();

    // 所有在参数中配置需要加载的扩展配置文件
    private String extraPathConfig;

    // 外置配置文件参数头
    public static final String PATH_CONFIG = "xjm.config.path";

    // private List<String> extraPathConfig;

    public PropertySourceLoader(String... args) {
        log.debug(String.format("开始解析命令行参数[%s]", Arrays.toString(args)));
        Assert.notNull(args, "args 必须配置参数");
        CommandLinePropertySource commandLinePropertySource = new CommandLinePropertySource(args);
        List<String> optionValues = commandLinePropertySource.getOptionValues(PATH_CONFIG);
        Assert.notEmpty(optionValues, String.format("请检查启动时是否带有外置配置文件参数: %s", PATH_CONFIG));
        extraPathConfig = optionValues.get(0);
        propertySources.add(commandLinePropertySource);
        this.loadExtraConfig();
    }

    /**
     * 加载外部的配置文件
     * */
    private void loadExtraConfig() {
        /*for (String filePath : extraPathConfig) {
            Assert.isTrue(FileUtil.isDirectory(filePath), String.format("参数[%s] 请设置配置文件，" +
                    "设置配置文件路径将导致失败: %s", PATH_CONFIG, filePath));
            this.propertySources.add(new ExtraConfigPropertySource(FileUtil.readLines(filePath, StandardCharsets.UTF_8)));
        }*/

        Assert.isTrue(FileUtil.isFile(extraPathConfig), String.format("参数[%s] 请设置配置文件，" +
                "设置配置文件路径将导致失败: %s", PATH_CONFIG, extraPathConfig));
        log.debug(String.format("开始解析外置配置文件[%s]", extraPathConfig));
        this.propertySources.add(new ExtraConfigPropertySource(FileUtil.readLines(extraPathConfig, StandardCharsets.UTF_8)));
    }

    /**
     * 根据名称获取对应的配置文件数据包装对象 PropertySource
     * @param name 配置文件名称
     * @return PropertySource配置数据包装对象
     * */
    public PropertySource<?> getPropertySourceByName(String name) {
        for (PropertySource<?> ps: this.propertySources) {
            if (ps.getName().equals(name)) {
                return ps;
            }
        }
        return null;
    }

    public String getExtraPathConfig() {
        return extraPathConfig;
    }

    public void setExtraPathConfig(String extraPathConfig) {
        this.extraPathConfig = extraPathConfig;
    }

    /*public List<String> getExtraPathConfig() {
        return extraPathConfig;
    }

    public void setExtraPathConfig(List<String> extraPathConfig) {
        this.extraPathConfig = extraPathConfig;
    }*/
}
